package com.dycong.common.common;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Random;

/**
 * Created by yu on 16-8-12.
 */
public class PasswordUtil {

    static final int SALT_LENGTH = 4;
    static final int SSHA_SOURCE_LENGTH = 20;
    static final String SSHA_PREFIX = "{SSHA}";

    public static boolean compareLdapPassword(String plain, String hashed){
        if(hashed.startsWith(SSHA_PREFIX)){
            return hashed.equals(ssha(plain, fetchSshaSalt(hashed)));
        }else{
            //TODO
            throw new RuntimeException("not implemented");
        }
    }


    public static String ssha(String asciiPassword) {
        return ssha(asciiPassword, seed());
    }

    public static String ssha(String asciiPassword, byte[] salt) {
        try {
            byte[] source = asciiPassword.getBytes("ascii");
            byte[] withSalt = new byte[source.length + SALT_LENGTH];
            System.arraycopy(source, 0, withSalt, 0, source.length);
            System.arraycopy(salt, 0, withSalt, source.length, SALT_LENGTH);
            byte[] sha1 = ByteArrayUtil.toSha1(withSalt);
            byte[] result = new byte[SSHA_SOURCE_LENGTH + SALT_LENGTH];
            System.arraycopy(sha1, 0, result, 0, SSHA_SOURCE_LENGTH);
            System.arraycopy(salt, 0, result, SSHA_SOURCE_LENGTH, SALT_LENGTH);
            return SSHA_PREFIX + base64Encode(result);
        } catch (UnsupportedEncodingException e) {
            //never here
            throw new RuntimeException(e);
        }
    }


    public void test(boolean a){

    }

    static byte[] fetchSshaSalt(String ssha) {
        if (!ssha.startsWith(SSHA_PREFIX))
            throw new IllegalArgumentException("ssha password must be start with " + SSHA_PREFIX);
        String base64 = ssha.substring(SSHA_PREFIX.length());
        byte[] salt = new byte[SALT_LENGTH];
        byte[] sshaBytes = base64Decode(base64);
        System.arraycopy(sshaBytes, SSHA_SOURCE_LENGTH, salt, 0, SALT_LENGTH);
        return salt;
    }

    public static byte[] seed() {
        Random random = new Random();
        return ByteBuffer.allocate(4).putInt(random.nextInt()).array();
    }


    static String base64Encode(byte[] source) {
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(source);
    }


    static byte[] base64Decode(String base64) {
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            return decoder.decodeBuffer(base64);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
